package factorytest.iflytek.com.einkiflytekfactorytest.factorytestui;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Message;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import factorytest.iflytek.com.einkiflytekfactorytest.R;
import factorytest.iflytek.com.einkiflytekfactorytest.common.FTUtils;
import factorytest.iflytek.com.einkiflytekfactorytest.common.PermissionManager;
import factorytest.iflytek.com.einkiflytekfactorytest.config.HtfyunBuildConfig;
import factorytest.iflytek.com.einkiflytekfactorytest.utils.DebugLog;

public class FactoryWifiListActivity extends FactoryBaseActivity implements View.OnClickListener {

    private TextView txtWifiInfo;

    private Button btnScan;

    private ListView wifiListView;

    private WifiListAdapter wifiListAdapter;

    private WifiManager mWifiManager;

    @Override
    int getLayoutId() {
        return R.layout.activity_factory_wifi_list;
    }

    @Override
    void onInitView(@Nullable Bundle savedInstanceState) {

        TextView tips = (TextView) findViewById(R.id.txtTips);
        tips.setText(getString(R.string.wifi_test_info, HtfyunBuildConfig.WIFI_MIN_RSSI));

        txtWifiInfo = (TextView) findViewById(R.id.txtWifiInfo);
        wifiListView = (ListView) findViewById(R.id.wifiListView);

        btnScan = (Button) findViewById(R.id.btnScan);
        btnScan.setOnClickListener(this);

        mWifiManager = getSystemService(WifiManager.class);
        wifiListAdapter = new WifiListAdapter(mContext);
        wifiListView.setAdapter(wifiListAdapter);

        if (!isWifiGotPermission()) {
            initWifiPermission();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (isWifiEnabled()) {
            startScanWifi();
        } else {
            openWiFi();
        }

        registerWifiReceiver(mContext);

    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterWifiReceiver(mContext);
        getHandler().removeMessages(MSG_WIFI_PASS);
        getHandler().removeMessages(MSG_WIFI_SCAN);
    }

    private void sendWifiPass() {
        if (!getHandler().hasMessages(MSG_WIFI_PASS)) {
            getHandler().sendEmptyMessageDelayed(MSG_WIFI_PASS, DELAY_WIFI_PASS);
        }
    }

    private final int MSG_WIFI_PASS = 100;
    private final int DELAY_WIFI_PASS = 800;

    private final int MSG_WIFI_SCAN = 101;
    private final int PERIOD_WIFI_SCAN = 3000;


    @Override
    void onHandleMessage(Handler handler, Message msg) {

        switch (msg.what) {
            case MSG_WIFI_PASS:
                finishWithOK();
                break;
            case MSG_WIFI_SCAN:
                scanWifi();
                DebugLog.e("MSG_WIFI_SCAN");
                handler.sendEmptyMessageDelayed(MSG_WIFI_SCAN, PERIOD_WIFI_SCAN);
                break;
        }
    }

    @Override
    public void onClick(View v) {

        if (v == btnScan) {
            startScanWifi();
        }
    }

    private void startScanWifi() {
        getHandler().sendEmptyMessage(MSG_WIFI_SCAN);
    }

    private boolean isWifiGotPermission() {

        return !((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED));

    }

    private void initWifiPermission() {

        if (isWifiGotPermission()) {
            return;
        }

        //同时申请多个权限
        PermissionManager.getInstance(getApplicationContext()).execute(this,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION);

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionManager.getInstance(getApplicationContext()).
                onRequestPermissionsResult(requestCode, permissions, grantResults);

    }



    private void scanWifi() {

        mWifiManager.startScan();
    }

    private boolean isWifiEnabled() {
        return null != mWifiManager && mWifiManager.isWifiEnabled();
    }
    /**
     * 打开Wifi
     */
    private void openWiFi() {
        if (!isWifiEnabled() && null != mWifiManager) {
            mWifiManager.setWifiEnabled(true);
        }
    }

    /**
     * 关闭Wifi
     */
    private void closeWiFi() {
        if (isWifiEnabled() && null != mWifiManager) {
            mWifiManager.setWifiEnabled(false);
        }
    }

    private void onWifiScanResult(List<ScanResult> scanResults) {
        if (scanResults == null || scanResults.isEmpty()) {
            return;
        }

        List<ScanResult> resultList = new ArrayList<>(scanResults);

        Collections.sort(resultList, new Comparator<ScanResult>() {
            @Override
            public int compare(ScanResult o1, ScanResult o2) {
                return o2.level - o1.level;
            }
        });

        ScanResult strongestResult = resultList.get(0);
        boolean pass = strongestResult.level >= HtfyunBuildConfig.WIFI_MIN_RSSI;

//        String result = getResultByCheckFactoryTestItemsEnum(FactoryTestItemsEnum.wifi, pass);
//        String result = getResultByCheckFactoryTestItemsEnum(FactoryTestItemsEnum.wifi, pass);
        String result = mContext.getString(R.string.test_result_fail);
        if (pass) {
            result = mContext.getString(R.string.test_result_pass);
            sendWifiPass();
        }

        String infoString = mContext.getString(R.string.ft_wifi_ssid_scan, strongestResult.SSID, strongestResult.level, result);

        final SpannableString msp = getSpannableString(infoString);

        txtWifiInfo.setText(msp);

        wifiListAdapter.refreshData(resultList);

    }


    @NonNull
    private SpannableString getSpannableString(String infoString) {
        final SpannableString msp = new SpannableString(infoString);
        String resultSearch = getString(R.string.ft_use_result_for_search);
        int index = infoString.indexOf(resultSearch);
        if (index > 0) {
            msp.setSpan(new RelativeSizeSpan(1.5f), index, infoString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            msp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), index, infoString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            msp.setSpan(new UnderlineSpan(), index, infoString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return msp;
    }

    private String getResultByCheckFactoryTestItemsEnum(FactoryTestItemsEnum itemsEnum, boolean pass) {

        String result = itemsEnum.getResultForAfterAging(mContext);

        if (FTUtils.isFactoryTestItemsAllPassed() && itemsEnum.isKeepTestAfterAging()) {

            if (pass && !itemsEnum.isPassedForAfterAging(mContext)) {
                result = mContext.getString(R.string.test_result_pass);

                itemsEnum.setResultForAfterAging(mContext, result);

            }

            return result;
        }

        result = itemsEnum.getResult(mContext);

        if (pass && !itemsEnum.isPassed(mContext)) {
            result = mContext.getString(R.string.test_result_pass);

            itemsEnum.setResult(mContext, result);

        }

        return result;

    }

    public void registerWifiReceiver(Context context) {
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        context.getApplicationContext().registerReceiver(wifiReceiver, filter);
    }

    public void unregisterWifiReceiver(Context context) {
        context.getApplicationContext().unregisterReceiver(wifiReceiver);
    }

    private BroadcastReceiver wifiReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (null == action) {

                return;
            }

            if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                switch (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)) {
                    case WifiManager.WIFI_STATE_ENABLING:
                        break;
                    case WifiManager.WIFI_STATE_ENABLED:
                        startScanWifi();
                        break;
                    case WifiManager.WIFI_STATE_DISABLING:
                        break;
                    case WifiManager.WIFI_STATE_DISABLED:
                        break;
                    case WifiManager.WIFI_STATE_UNKNOWN:
                    default:
                        break;
                }
            } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {

                DebugLog.e("SCAN_RESULTS_AVAILABLE_ACTION");
                List<ScanResult> scanResultList = mWifiManager.getScanResults();
                onWifiScanResult(scanResultList);
            }

        }
    };


    private final class WifiListAdapter extends BaseAdapter {

        private static final String TAG = "WifiListAdapter";
        private List<ScanResult> scanResults;
        private Context mContext;
        private String connectedSSID;

        public WifiListAdapter(Context context) {
            mContext = context.getApplicationContext();
            this.scanResults = new ArrayList<>();
        }

        public String getConnectedSSID() {
            return connectedSSID;
        }

        public void setConnectedSSID(String connectedSSID) {
            this.connectedSSID = connectedSSID;

            refreshData(getScanResults());

        }


        public List<ScanResult> getScanResults() {
            return scanResults;
        }

        private List<ScanResult> getNewScanResultBySetConnectedSSIDFist(List<ScanResult> scanResults) {

            Collections.sort(scanResults, new Comparator<ScanResult>() {
                @Override
                public int compare(ScanResult o1, ScanResult o2) {
                    return o2.level- o1.level;
                }
            });

            if (TextUtils.isEmpty(connectedSSID)) {

                return scanResults;
            }

            Iterator<ScanResult> it = scanResults.iterator();

            ScanResult first = null;
            while(it.hasNext()){
                ScanResult x = it.next();

                if(x.SSID.replaceAll("\"", "").equals(connectedSSID.replaceAll("\"", ""))){
                    it.remove();
                    first = x;
                    break;
                }
            }

            if (first != null) {
                scanResults.add(0, first);

            }

            return scanResults;

        }

        public void clearData() {
            scanResults.clear();
            notifyDataSetChanged();
        }

        public void refreshData(List<ScanResult> scanResults) {
            if (null != scanResults) {
                // 去重
                List<ScanResult> newScanResults = excludeRepetition(scanResults);

                // 清空数据
                this.scanResults.clear();
                // 更新数据
                this.scanResults.addAll(getNewScanResultBySetConnectedSSIDFist(newScanResults));
            }
            // 更新显示
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return scanResults.size();
        }

        @Override
        public Object getItem(int position) {
            return scanResults.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView != null) {
                holder = (ViewHolder)convertView.getTag();
            }

            if (holder == null) {
                holder = new ViewHolder();
                LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.item_wifi_devices, null);
                holder.txtName = (TextView) convertView.findViewById(R.id.txtName);
                holder.txtRSSI = (TextView) convertView.findViewById(R.id.txtRSSI);
                holder.txtCapabilities = (TextView) convertView.findViewById(R.id.txtCapabilities);

                convertView.setTag(holder);
            }

            ScanResult scanResult = scanResults.get(position);

            holder.txtName.setText(getString(R.string.wifi_rssi_name, scanResult.SSID));

            holder.txtRSSI.setText(getString(R.string.wifi_signal_strength, scanResult.level));//(WifiManager.calculateSignalLevel(scanResult.level, 5) + "/5")));
            holder.txtCapabilities.setText(getString(R.string.wifi_capabilities, scanResult.capabilities));

            return convertView;
        }

        /**
         * 排除重复
         *
         * @param scanResults 带处理的数据
         * @return 去重数据
         */
        private List<ScanResult> excludeRepetition(List<ScanResult> scanResults) {
            HashMap<String, ScanResult> hashMap = new HashMap<>();

            for (ScanResult scanResult : scanResults) {
                String ssid = scanResult.SSID;

                if (TextUtils.isEmpty(ssid)) {
                    continue;
                }

                ScanResult tempResult = hashMap.get(ssid);
                if (null == tempResult) {
                    hashMap.put(ssid, scanResult);
                    continue;
                }

                if (WifiManager.calculateSignalLevel(tempResult.level, 100) < WifiManager.calculateSignalLevel(scanResult.level, 100)) {
                    hashMap.put(ssid, scanResult);
                }
            }

            List<ScanResult> results = new ArrayList<>();
            for (Map.Entry<String, ScanResult> entry : hashMap.entrySet()) {
                results.add(entry.getValue());
            }

            return results;
        }
    }

    private class ViewHolder {
        private TextView txtName;
        private TextView txtRSSI;
        private TextView txtCapabilities;
    }

}
